
//
// An example of encoding/decoding object
//

package main

import "encoding/gob"
import "fmt"
import "os"
import "atomutil"

type Op struct {
    X int
    Y int
}

type PaxosState struct {
	Np int
	Na int
	Va interface{}

	Decided  bool
	DecidedV interface{}

	InsId int // instance id
}


func speedtest() {
    fo, _ := os.Create("a.bin")
    defer fo.Close()
    enc := gob.NewEncoder(fo)
    
    for i := 1; i <= 100; i++ {
        op := &PaxosState{}
        op.Va = "Get 1"
        err := enc.Encode(op)
        if err != nil { fmt.Println(err) }
        fo.Sync()
    }
    //fo.Sync()
}

func speedtest2() {

    for i := 1; i <= 100; i++ {
        op := &PaxosState{}
        op.Va = "Get 1"
        err := atomutil.WriteData("a.bin", op)    
        if err != nil { fmt.Println(err) }
    }
}
 
func writeOp() {
    fo, _ := os.Create("a.bin")
    defer fo.Close()
    enc := gob.NewEncoder(fo)
    
    for i := 1; i <= 10; i++ {
        op := &Op{i, i}
        enc.Encode(op)
        //fo.Sync()
    }
    
    pos, err := fo.Seek(10, 0)
    err = fo.Truncate(0)
    fmt.Printf("Truncated file. pos=%v err=%v\n", pos, err)
    enc = gob.NewEncoder(fo)
    for i := 11; i <= 20; i++ {
        op := &Op{i, i}
        enc.Encode(op)
        //fo.Sync()
    }
} 

func readOp() {
    fi, _ := os.Open("a.bin")
    defer fi.Close()
   
    var op *Op
    dec := gob.NewDecoder(fi)
    
    for i := 1; i <= 20; i++ {
        err := dec.Decode(&op) 
        fmt.Printf("Get op: %v err: %v\n", op, err)
    }
}

func test() {

    fo, _ := os.Create("b.bin")
    defer fo.Close()
    fi, _ := os.Open("b.bin")
    defer fi.Close()
 
    enc := gob.NewEncoder(fo)
    dec := gob.NewDecoder(fi)
   

    for i := 1; i <= 10; i++ {
        var op *Op
        var op2 *Op
        op = &Op{i, i}
        enc.Encode(op)

        pos, err := fi.Seek(0, 1)
        err = dec.Decode(&op2)
        fmt.Printf("Get op: %v at %v err: %v\n", op2, pos, err)

        pos, err = fi.Seek(0, 1)
        err = dec.Decode(&op2)
        fmt.Printf("Get op: %v at %v err: %v\n", op2, pos, err)
    }
}

func main() {
//   writeOp()
//   readOp()
//   test()
   speedtest()
//    speedtest2()
}
